using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.MediaCenter;
using Microsoft.MediaCenter.Hosting;
using Microsoft.MediaCenter.UI;
using System;
using System.Collections;
using System.IO;
using MyMoviesBrowserLibrary;
using System.Text;

namespace MyMoviesBrowser
{
    public class Application : ModelItem
    {
        private static Application singleApplicationInstance;
        private AddInHost host;
        private HistoryOrientedPageSession session;
        private MainMenu mainMenu;
        private string currentFile { get; set; }
        private Settings settings;
        private bool first = true;
        private long previousCall;
        private bool transition;
        private TimeSpan tempPosition;
        private MediaTransport transport;

        private Queue<MediaFile> mediaQueue = new Queue<MediaFile>();

        public static Application Current
        {
            get
            {
                return singleApplicationInstance;
            }
        }

        public Application()
            : this(null, null)
        {
        }

        public Application(HistoryOrientedPageSession session, AddInHost host)
        {
            this.session = session;
            this.host = host;
            singleApplicationInstance = this;

            settings = Settings.Default;

            mainMenu = new MainMenu();
                        
        }
                
        public MediaCenterEnvironment MediaCenterEnvironment
        {
            get
            {
                if (host == null) return null;
                return host.MediaCenterEnvironment;
            }
        }

        public void GoToMenu()
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["MainMenu"] = mainMenu;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/Menu", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToMovieMenu(MovieMenu movieMenu)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["MovieMenu"] = movieMenu;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/MovieMenu", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToTVMenu(TVMenu tvMenu)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["TVMenu"] = tvMenu;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/TVMenu", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToGalleryPage(MovieGallery gallery)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["MovieGallery"] = gallery;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/MovieGallery", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToGalleryPage(TrailerGallery gallery)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["TrailerGallery"] = gallery;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/TrailerGallery", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToDetailsPage(MyMovie movie)
        {
            if(movie.Files == null)
                movie.GetFiles();

            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Application"] = this;
            properties["Movie"] = movie;
            
            if (string.IsNullOrEmpty(movie.FolderImage))
                movie.Image = new Image("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/NoImage");
            else
                movie.Image = new Image("file://" + movie.FolderImage);



            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/MovieDetailsPage", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }
        public void GoToDetailsPage(Trailer movie)
        {
            if (movie.Files == null)
                movie.GetFiles();

            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Application"] = this;
            properties["Movie"] = movie;

            if (string.IsNullOrEmpty(movie.MovieTrailer.PosterLocation))
                movie.Image = new Image("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/NoImage");
            else
                movie.Image = new Image("file://" + movie.MovieTrailer.PosterLocation);



            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/TrailerDetailsPage", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToTrailerMenu(TrailerMenu trailerMenu)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["TrailerMenu"] = trailerMenu;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/TrailerMenu", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToGalleryPage(SeriesGallery gallery)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["SeriesGallery"] = gallery;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/SeriesGallery", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToGalleryPage(SeasonGallery gallery)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["SeasonGallery"] = gallery;

            if (gallery.CurrentSeries.Seasons.Count == 1)
            {
                GoToGalleryPage(new EpisodeGallery(gallery.CurrentSeries.Seasons[0]));
                return;
            }

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/SeasonGallery", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToGalleryPage(EpisodeGallery gallery)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["EpisodeGallery"] = gallery;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/EpisodeGallery", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void GoToGalleryPage(ActorsGallery gallery)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["ActorsGallery"] = gallery;

            if (session != null)
            {
                session.GoToPage("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/ActorsGallery", properties);
            }
            else
            {
                Debug.WriteLine("GoToMenu");
            }
        }

        public void PlayMedia(MediaFile mediaFile, MyMovie movie)
        {
            movie.CheckBoxItem.Value = true;
            currentFile = mediaFile.Path;
            if (movie.WatchTrailersCheckBoxItem.Value && movie.NumberOfTrailersToPlay > 0)
            {
                List<string> trailers = MyMoviesBrowserBusiness.GetSimilarTrailers(movie.MovieTitle, movie.NumberOfTrailersToPlay);
                MediaCenterEnvironment mce = host.MediaCenterEnvironment;

                StringBuilder sb = new StringBuilder(@"<?wpl verion=""1.0""?><smil><body><seq>");
                
                foreach (string trailer in trailers)
                {
                    sb.AppendFormat(@"<media src=""{0}"" />", trailer);
                }
                sb.AppendFormat(@"<media src=""{0}"" />", mediaFile.Path);
                sb.Append(@"</seq></body></smil>");
                string playlist = Path.Combine(Settings.DataFolder, "playlist.wpl");
                File.WriteAllText(playlist,sb.ToString());
                
                PlayMedia(playlist);
            }
            else
                PlayMedia(mediaFile.Path);
        }

        public void PlayMedia(MediaFile mediaFile, Trailer trailer)
        {
            trailer.CheckBoxItem.Value = true;
            currentFile = mediaFile.Path;
            PlayMedia(mediaFile.Path);
        }

        public void PlayMedia(MediaFile mediaFile)
        {
            currentFile = mediaFile.Path;
            PlayMedia(mediaFile.Path);
        }

        public void PlayMedia(string mediaFile)
        {
            transition = false;
            MediaCenterEnvironment mce = host.MediaCenterEnvironment;
                        
            tempPosition = TimeSpan.FromSeconds(MyMoviesBrowserBusiness.GetPlaybackTime(currentFile));
            if (tempPosition.TotalSeconds > 1)
            {
                IEnumerable buttons = new object[] {
                            Resources.Dialog_Resume,
                            Resources.Dialog_Restart
                        };
                mce.Dialog(
                    string.Format("Resume playback at {0}?",
                    FormatTimespan(tempPosition)),
                    "Resume Playback?",
                    buttons, 0, true, null,
                    delegate(DialogResult dialogResult)
                    {
                        transition = (int)dialogResult == 100;
                    });
            }

            MyMoviesBrowserBusiness.SetPlayed(currentFile, true);

            if(mediaFile.StartsWith("DVD"))
                mce.PlayMedia(MediaType.Dvd, mediaFile, false);
            else
                mce.PlayMedia(MediaType.Video, mediaFile, false);
            if (transport != mce.MediaExperience.Transport)
            {
                if (transport != null)
                    transport.PropertyChanged -= new PropertyChangedEventHandler(Transport_PropertyChanged);
                transport = mce.MediaExperience.Transport;
                transport.PropertyChanged += new PropertyChangedEventHandler(Transport_PropertyChanged);
            }
            //if (first)
            //{
            //    mce.MediaExperience.Transport.PropertyChanged += new Microsoft.MediaCenter.UI.PropertyChangedEventHandler(Transport_PropertyChanged);
            //    first = false;
            //}
            mce.MediaExperience.GoToFullScreen();
            if (transition && mediaFile == currentFile)
                TransitionToTime(tempPosition);
        }

        void Transport_PropertyChanged(IPropertyObject sender, string property)
        {
            try
            {
                MediaExperience mc = host.MediaCenterEnvironment.MediaExperience;
                MediaTransport transport = sender as MediaTransport;
                string title = mc.MediaMetadata["Title"].ToString().Replace(" (playlist)", "");
                string temp = Path.GetFileNameWithoutExtension(currentFile);
                //Debug.WriteLine(string.Format("title: {0}; temp: {1}; Property: {2}; Playstate: {3}; Position: {4}", mc.MediaMetadata["Title"],temp, property, transport.PlayState, transport.Position));
                if (property == "PlayState")
                {
                    if (transport.PlayState == PlayState.Finished)
                    {
                        MyMoviesBrowserBusiness.SetPlaybackTime(currentFile, (int)transport.Position.TotalSeconds);
                    }
                    else if (transport.PlayState == PlayState.Playing && transition && temp.StartsWith(title) && tempPosition != null)
                    {
                        Debug.WriteLine("Transition: " + currentFile);
                        transition = false;
                        TransitionToTime(tempPosition);
                    }
                }

                if (property == "Position" && temp.StartsWith(title))
                {
                    long currentCall = DateTime.Now.Ticks / 10000000L;
                    if (currentCall == previousCall)
                        return;
                    previousCall = currentCall;

                    Debug.WriteLine("SetPlayback: " + currentFile);
                    MyMoviesBrowserBusiness.SetPlaybackTime(currentFile, (int)transport.Position.TotalSeconds);
                }
            }
            catch { }
        }

        private string FormatTimespan(TimeSpan span)
        {
            return string.Format("{0}:{1}:{2}", span.Hours, span.Minutes.ToString().PadLeft(2, '0'), span.Seconds.ToString().PadLeft(2, '0'));
        }

        private MediaTransport CurrentMediaTransport
        {
            get
            {
                MediaCenterEnvironment env = host.MediaCenterEnvironment;
                if (env != null)
                {
                    MediaExperience exp = env.MediaExperience;

                    if (exp != null) return exp.Transport;
                }
                return null;
            }
        }

        private bool TransitionToTime(TimeSpan time)
        {
            MediaTransport transport = CurrentMediaTransport;
            if (transport != null)
            {
                // Make relative jumps instead of absolute if appropriate
                //if (_jumpIsRelative) time = time.Add(transport.Position);

                // Make the jump
                transport.Position = time;
                return true;
            }
            return false;
        }
    }
}